package com.gzc.just.play.last.war.sceneserver.battle;

import com.gzc.just.play.last.war.sceneserver.SceneWorkThreadManager;
import com.gzc.just.play.last.war.sceneserver.ai.AIManager;
import com.gzc.just.play.last.war.sceneserver.config.SceneConfig;
import com.gzc.just.play.last.war.protobuf.cs.cstoss.CSToSS;
import com.gzc.just.play.last.war.protobuf.ss.sstocs.SSToCS;
import com.gzc.just.play.last.war.protobuf.ss.sstogs.SSToGS;
import com.google.protobuf.Message;
import com.gzc.just.play.last.war.common.net.NetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 场景战斗管理器
 * 对应C++的CSSBattleMgr类，负责管理场景中的战斗实例
 */
@Component("sceneBattleCoordinator")
public class SceneBattleManager {
    private static final Logger logger = LoggerFactory.getLogger(SceneBattleManager.class);
    
    @Autowired
    private SceneConfig sceneConfig;
    
    @Autowired
    private SceneWorkThreadManager sceneWorkThreadManager;
    
    @Autowired
    @Lazy
    private AIManager aiManager;
    
    // 战斗实例映射表
    private final ConcurrentHashMap<Long, SceneBattle> battleMap = new ConcurrentHashMap<>();
    
    // 战斗ID生成器
    private final AtomicLong battleIdGenerator = new AtomicLong(1000);
    
    // 待删除战斗队列
    private final Queue<Long> battlesToRemove = new LinkedList<>();
    
    // 最大战斗数量
    private int maxBattleCount;
    
    @PostConstruct
    public void init() {
        this.maxBattleCount = sceneConfig.getMaxBattleCount();
        logger.info("SceneBattleManager initialized with max battle count: {}", maxBattleCount);
    }
    
    @PreDestroy
    public void destroy() {
        // 清理所有战斗
        for (SceneBattle battle : battleMap.values()) {
            battle.destroy();
        }
        battleMap.clear();
        
        logger.info("SceneBattleManager destroyed");
    }
    
    /**
     * 创建新战斗
     */
    public SceneBattle createBattle(long creatorId, String battleName, int mapId, int maxPlayers) {
        if (battleMap.size() >= maxBattleCount) {
            logger.warn("Cannot create battle, reached max battle count: {}", maxBattleCount);
            return null;
        }
        
        long battleId = battleIdGenerator.incrementAndGet();
        SceneBattle battle = new SceneBattle(battleId, creatorId, battleName, mapId, maxPlayers);
        
        battleMap.put(battleId, battle);
        logger.info("Created new battle: {}, name: {}, map: {}, creator: {}", 
                   battleId, battleName, mapId, creatorId);
        
        // 通知CentralServer战斗已创建
        notifyBattleCreated(battle);
        
        return battle;
    }
    
    /**
     * 获取战斗实例
     */
    public SceneBattle getBattle(long battleId) {
        return battleMap.get(battleId);
    }
    
    /**
     * 获取所有战斗实例
     */
    public Collection<SceneBattle> getAllBattles() {
        return battleMap.values();
    }
    
    /**
     * 获取当前战斗数量
     */
    public int getBattleCount() {
        return battleMap.size();
    }
    
    /**
     * 删除战斗
     */
    public boolean removeBattle(long battleId) {
        SceneBattle battle = battleMap.remove(battleId);
        if (battle != null) {
            battlesToRemove.add(battleId);
            logger.info("Scheduled battle {} for removal", battleId);
            return true;
        }
        return false;
    }
    
    /**
     * 处理战斗消息
     */
    public boolean handleBattleMessage(long battleId, Message message, int msgId) {
        SceneBattle battle = battleMap.get(battleId);
        if (battle == null) {
            logger.error("Battle {} not found", battleId);
            return false;
        }
        
        try {
            battle.handleMessage(message, msgId);
            return true;
        } catch (Exception e) {
            logger.error("Error handling message {} for battle {}", msgId, battleId, e);
            return false;
        }
    }
    
    /**
     * 通知CentralServer战斗已创建
     * 注：当前禁用，等待proto消息定义更新
     */
    private void notifyBattleCreated(SceneBattle battle) {
        try {
            logger.debug("Battle created: {}, name: {}, map: {}, creator: {}",
                        battle.getBattleId(), battle.getBattleName(), battle.getMapId(), battle.getCreatorId());
            // 消息定义待定
        } catch (Exception e) {
            logger.error("Failed to notify battle creation", e);
        }
    }
    
    /**
     * 定时清理已结束的战斗
     */
    @Scheduled(fixedDelay = 10000) // 每10秒执行一次
    public void cleanupFinishedBattles() {
        Iterator<Long> iterator = battlesToRemove.iterator();
        while (iterator.hasNext()) {
            Long battleId = iterator.next();
            
            // 检查战斗是否可以安全删除（例如，所有玩家已断开连接）
            SceneBattle battle = battleMap.get(battleId);
            if (battle == null || battle.canSafelyRemove()) {
                if (battle != null) {
                    battle.destroy();
                    // 通知CentralServer战斗已删除
                    notifyBattleRemoved(battleId);
                }
                iterator.remove();
            }
        }
    }
    
    /**
     * 通知CentralServer战斗已删除
     * 注：当前禁用，等待proto消息定义更新
     */
    private void notifyBattleRemoved(long battleId) {
        try {
            logger.debug("Battle removed: {}", battleId);
            // 消息定义待定
        } catch (Exception e) {
            logger.error("Failed to notify battle removal", e);
        }
    }
    
    /**
     * 广播消息到战斗中的所有玩家
     */
    public boolean broadcastToBattle(long battleId, Message message, int msgId) {
        SceneBattle battle = battleMap.get(battleId);
        if (battle == null) {
            logger.error("Battle {} not found for broadcast", battleId);
            return false;
        }
        
        try {
            battle.broadcast(message);
            return true;
        } catch (Exception e) {
            logger.error("Failed to broadcast to battle {}", battleId, e);
            return false;
        }
    }
    
    /**
     * 获取战斗统计信息
     */
    public Map<String, Object> getBattleStatistics() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalBattles", battleMap.size());
        stats.put("maxBattles", maxBattleCount);
        stats.put("activePlayers", getAllActivePlayerCount());
        
        // 按状态统计战斗数量
        Map<String, Integer> statusCount = new HashMap<>();
        for (SceneBattle battle : battleMap.values()) {
            String status = battle.getStatus().name();
            statusCount.put(status, statusCount.getOrDefault(status, 0) + 1);
        }
        stats.put("battlesByStatus", statusCount);
        
        return stats;
    }
    
    /**
     * 获取所有战斗中的活跃玩家总数
     */
    private int getAllActivePlayerCount() {
        int totalPlayers = 0;
        for (SceneBattle battle : battleMap.values()) {
            totalPlayers += battle.getPlayerCount();
        }
        return totalPlayers;
    }
    
    /**
     * 内部类：场景战斗实例
     * 对应C++的CSSBattle类
     */
    public static class SceneBattle {
        private static final Logger logger = LoggerFactory.getLogger(SceneBattle.class);
        
        private final long battleId;
        private final long creatorId;
        private final String battleName;
        private final int mapId;
        private final int maxPlayers;
        
        // 战斗状态
        private BattleStatus status = BattleStatus.WAITING;
        
        // 玩家映射表
        private final ConcurrentHashMap<Long, BattlePlayer> players = new ConcurrentHashMap<>();
        
        // AI实体映射表
        private final ConcurrentHashMap<Long, AIEntity> aiEntities = new ConcurrentHashMap<>();
        
        // 战斗创建时间
        private final long createTime = System.currentTimeMillis();
        
        // 最后活动时间
        private volatile long lastActivityTime = System.currentTimeMillis();
        
        public SceneBattle(long battleId, long creatorId, String battleName, int mapId, int maxPlayers) {
            this.battleId = battleId;
            this.creatorId = creatorId;
            this.battleName = battleName;
            this.mapId = mapId;
            this.maxPlayers = maxPlayers;
            
            // 创建者自动加入战斗
            joinPlayer(creatorId, "Creator");
        }
        
        /**
         * 加入战斗
         */
        public boolean joinPlayer(long playerId, String playerName) {
            if (players.size() >= maxPlayers) {
                logger.warn("Battle {} is full, cannot join player {}", battleId, playerId);
                return false;
            }
            
            if (players.containsKey(playerId)) {
                logger.warn("Player {} already in battle {}", playerId, battleId);
                return false;
            }
            
            BattlePlayer player = new BattlePlayer(playerId, playerName);
            players.put(playerId, player);
            updateLastActivity();
            
            logger.info("Player {} ({}) joined battle {}", playerId, playerName, battleId);
            return true;
        }
        
        /**
         * 离开战斗
         */
        public boolean leavePlayer(long playerId) {
            BattlePlayer player = players.remove(playerId);
            if (player != null) {
                updateLastActivity();
                logger.info("Player {} ({}) left battle {}", playerId, player.getName(), battleId);
                
                // 检查是否需要结束战斗
                if (players.isEmpty()) {
                    status = BattleStatus.FINISHED;
                }
                return true;
            }
            return false;
        }
        
        /**
         * 处理战斗消息
         */
        public void handleMessage(Message msg, int msgId) {
            updateLastActivity();
            
            // 根据消息类型处理不同的战斗操作
            logger.debug("Handling battle message: msgId={}", msgId);
            // 注：当前暂无具体的战斗消息处理逻辑
            // 消息类型需要与实际的proto定义保持一致
        }
        
        /**
         * 广播消息给战斗中的所有玩家
         */
        public void broadcast(Message msg) {
            // 通过GateServer广播消息
            // 这里简化处理，实际应该通过GateServerManager发送
            logger.debug("Broadcasting message to {} players in battle {}", players.size(), battleId);
        }
        
        /**
         * 检查是否可以安全删除
         */
        public boolean canSafelyRemove() {
            return status == BattleStatus.FINISHED && 
                   (System.currentTimeMillis() - lastActivityTime) > 60000; // 1分钟后可以删除
        }
        
        /**
         * 销毁战斗
         */
        public void destroy() {
            players.clear();
            aiEntities.clear();
            logger.info("Battle {} destroyed", battleId);
        }
        
        // 处理各种战斗消息的方法
        // 注：具体处理方法需要根据实际的proto消息定义来实现
        
        private void updateLastActivity() {
            lastActivityTime = System.currentTimeMillis();
        }
        
        // Getter方法
        public long getBattleId() {
            return battleId;
        }
        
        public long getCreatorId() {
            return creatorId;
        }
        
        public String getBattleName() {
            return battleName;
        }
        
        public int getMapId() {
            return mapId;
        }
        
        public int getMaxPlayers() {
            return maxPlayers;
        }
        
        public BattleStatus getStatus() {
            return status;
        }
        
        public int getPlayerCount() {
            return players.size();
        }
        
        public Set<Long> getPlayerIds() {
            return new HashSet<>(players.keySet());
        }
        
        public BattlePlayer getPlayer(long playerId) {
            return players.get(playerId);
        }
        
        public Collection<BattlePlayer> getAllPlayers() {
            return new ArrayList<>(players.values());
        }
        
        public long getCreateTime() {
            return createTime;
        }
        
        public long getLastActivityTime() {
            return lastActivityTime;
        }
        
        // 战斗状态枚举
        public enum BattleStatus {
            WAITING,    // 等待中
            PLAYING,    // 游戏中
            FINISHED    // 已结束
        }
        
        // 战斗玩家类
        public static class BattlePlayer {
            private final long playerId;
            private final String name;
            private final long joinTime;
            private volatile long lastActionTime;
            
            public BattlePlayer(long playerId, String name) {
                this.playerId = playerId;
                this.name = name;
                this.joinTime = System.currentTimeMillis();
                this.lastActionTime = joinTime;
            }
            
            public void performAction(int actionType, String actionData) {
                lastActionTime = System.currentTimeMillis();
                logger.debug("Player {} performed action {}: {}", playerId, actionType, actionData);
            }
            
            // Getter方法
            public long getPlayerId() {
                return playerId;
            }
            
            public String getName() {
                return name;
            }
            
            public long getJoinTime() {
                return joinTime;
            }
            
            public long getLastActionTime() {
                return lastActionTime;
            }
        }
        
        // AI实体类
        public static class AIEntity {
            private final long entityId;
            private final String entityType;
            private final AIType aiType;
            private final long createTime;
            
            public AIEntity(long entityId, String entityType, AIType aiType) {
                this.entityId = entityId;
                this.entityType = entityType;
                this.aiType = aiType;
                this.createTime = System.currentTimeMillis();
            }
            
            // Getter方法
            public long getEntityId() {
                return entityId;
            }
            
            public String getEntityType() {
                return entityType;
            }
            
            public AIType getAiType() {
                return aiType;
            }
            
            public long getCreateTime() {
                return createTime;
            }
            
            // AI类型枚举
            public enum AIType {
                SOLDIER,    // 士兵
                HERO,       // 英雄
                BUILDING,   // 建筑
                MONSTER     // 怪物
            }
        }
    }
}